package com.example.users.service;

import org.springframework.stereotype.Service;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.beans.factory.annotation.Autowired;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class CaptchaService {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    private static final String CAPTCHA_PREFIX = "captcha:";
    private static final int CAPTCHA_EXPIRE_MINUTES = 5;
    private static final int CAPTCHA_WIDTH = 120;
    private static final int CAPTCHA_HEIGHT = 40;
    private static final String CAPTCHA_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

    /**
     * 生成验证码
     */
    public CaptchaResult generateCaptcha() {
        String captchaCode = generateRandomCode();
        BufferedImage image = createCaptchaImage(captchaCode);
        
        // 将图片转换为Base64
        String base64Image = imageToBase64(image);
        
        // 生成验证码ID
        String captchaId = generateCaptchaId();
        
        // 将验证码存储到Redis，5分钟过期
        redisTemplate.opsForValue().set(
            CAPTCHA_PREFIX + captchaId, 
            captchaCode, 
            CAPTCHA_EXPIRE_MINUTES, 
            TimeUnit.MINUTES
        );
        
        return new CaptchaResult(captchaId, base64Image);
    }

    /**
     * 验证验证码
     */
    public boolean validateCaptcha(String captchaId, String inputCode) {
        if (captchaId == null || inputCode == null) {
            return false;
        }
        
        String storedCode = redisTemplate.opsForValue().get(CAPTCHA_PREFIX + captchaId);
        if (storedCode == null) {
            return false;
        }
        
        // 验证成功后删除验证码
        redisTemplate.delete(CAPTCHA_PREFIX + captchaId);
        
        return storedCode.equalsIgnoreCase(inputCode);
    }

    /**
     * 生成随机验证码
     */
    private String generateRandomCode() {
        Random random = new Random();
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < 4; i++) {
            code.append(CAPTCHA_CHARS.charAt(random.nextInt(CAPTCHA_CHARS.length())));
        }
        return code.toString();
    }

    /**
     * 生成验证码ID
     */
    private String generateCaptchaId() {
        return System.currentTimeMillis() + "_" + new Random().nextInt(1000);
    }

    /**
     * 创建验证码图片
     */
    private BufferedImage createCaptchaImage(String code) {
        BufferedImage image = new BufferedImage(CAPTCHA_WIDTH, CAPTCHA_HEIGHT, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = image.createGraphics();
        
        // 设置抗锯齿
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        
        // 设置背景色
        g2d.setColor(Color.WHITE);
        g2d.fillRect(0, 0, CAPTCHA_WIDTH, CAPTCHA_HEIGHT);
        
        // 绘制干扰线
        Random random = new Random();
        for (int i = 0; i < 5; i++) {
            g2d.setColor(new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256)));
            g2d.drawLine(random.nextInt(CAPTCHA_WIDTH), random.nextInt(CAPTCHA_HEIGHT),
                        random.nextInt(CAPTCHA_WIDTH), random.nextInt(CAPTCHA_HEIGHT));
        }
        
        // 绘制验证码文字
        Font font = new Font("Arial", Font.BOLD, 24);
        g2d.setFont(font);
        
        for (int i = 0; i < code.length(); i++) {
            g2d.setColor(new Color(random.nextInt(100), random.nextInt(100), random.nextInt(100)));
            int x = 20 + i * 25;
            int y = 25 + random.nextInt(10);
            g2d.drawString(String.valueOf(code.charAt(i)), x, y);
        }
        
        g2d.dispose();
        return image;
    }

    /**
     * 将图片转换为Base64
     */
    private String imageToBase64(BufferedImage image) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            javax.imageio.ImageIO.write(image, "png", baos);
            byte[] imageBytes = baos.toByteArray();
            return "data:image/png;base64," + Base64.getEncoder().encodeToString(imageBytes);
        } catch (IOException e) {
            throw new RuntimeException("Failed to convert image to base64", e);
        }
    }

    /**
     * 验证码结果类
     */
    public static class CaptchaResult {
        private String captchaId;
        private String captchaImage;

        public CaptchaResult(String captchaId, String captchaImage) {
            this.captchaId = captchaId;
            this.captchaImage = captchaImage;
        }

        public String getCaptchaId() {
            return captchaId;
        }

        public void setCaptchaId(String captchaId) {
            this.captchaId = captchaId;
        }

        public String getCaptchaImage() {
            return captchaImage;
        }

        public void setCaptchaImage(String captchaImage) {
            this.captchaImage = captchaImage;
        }
    }
}
